package com.xbongbong.process;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasProcessDataEntity;
import com.xbongbong.paas.domain.entity.PaasProcessNodeTaskEntity;
import com.xbongbong.paas.domain.entity.PaasProcessTaskEntity;
import com.xbongbong.paas.domain.entity.ext.PaasProcessNodeTaskEntityExt;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.NodeTypeEnum;
import com.xbongbong.paas.enums.ProcessTypeEnum;
import com.xbongbong.paas.enums.TaskTypeEnum;
import com.xbongbong.paas.help.FormDataHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasProcessDataModel;
import com.xbongbong.paas.model.PaasProcessNodeTaskModel;
import com.xbongbong.paas.model.PaasProcessTaskModel;
import com.xbongbong.paas.pojo.dto.ProcessDataAddFormDataDTO;
import com.xbongbong.paas.pojo.dto.ProcessDataUpdateDTO;
import com.xbongbong.paas.pojo.dto.ProcessDataUpdateFormDataDTO;
import com.xbongbong.paas.pojo.dto.ProcessNodeTaskAddBatchDTO;
import com.xbongbong.paas.pojo.dto.ProcessNodeTaskAddDTO;
import com.xbongbong.paas.pojo.dto.ProcessNodeTaskUpdateDTO;
import com.xbongbong.paas.pojo.dto.ProcessTaskUpdateDTO;
import com.xbongbong.paas.pojo.vo.ProcessDataAddFormDataVO;
import com.xbongbong.paas.pojo.vo.ProcessTaskUpdateVO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.parent.help.PushMessageHelp;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.message.constant.ProcessPushConstant;
import com.xbongbong.pro.message.enums.PushTypeEnum;
import com.xbongbong.pro.message.pojo.PushRefTypePojo;
import com.xbongbong.pro.message.pojo.dto.MessageRabbitMqDTO;
import com.xbongbong.pro.process.pojo.dto.WorkrecordTaskDTO;
import com.xbongbong.pro.process.pojo.dto.WorkrecordTaskOption;
import com.xbongbong.pro.rabbitmq.producer.BaseProducer;
import com.xbongbong.pro.service.dingtalk.WorkflowDingtalkService;
import com.xbongbong.process.data.PaasProcessDataServiceImpl;
import com.xbongbong.process.data.ProcessDataSynchronizedFormService;
import com.xbongbong.process.ding.DingtalkWorkrecordService;
import com.xbongbong.process.task.PaasProcessTaskService;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.domain.entity.ext.WorkOrderFormEntityExt;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.model.WorkOrderFormModel;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.DepartmentModel;
import com.xbongbong.sys.model.UserModel;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @description: 流程操作help
 * @Author: hongxiao
 * @date: 2019-10-31 16:54
 * @since v4.5.0
 */
@Component
public class ProcessOperateHelp {

    private static  final Logger LOG = LoggerFactory.getLogger(ProcessOperateHelp.class);

    @Resource
    private PaasProcessTaskService paasProcessTaskService;
    @Resource
    private PaasProcessDataModel paasProcessDataModel;
    @Resource
    private ProcessDataSynchronizedFormService processDataSynchronizedFormService;
    @Resource
    private FormDataHelp formDataHelp;
    @Resource
    private PaasProcessDataServiceImpl paasProcessDataService;
    @Resource
    private UserModel userModel;
    @Resource
    private DepartmentModel departmentModel;
    @Resource
    private PaasProcessNodeTaskModel paasProcessNodeTaskModel;
    @Resource
    private WorkOrderFormModel workOrderFormModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private PushMessageHelp pushMessageHelp;
    @Resource
    private BaseProducer baseProducer;
    @Resource
    private PaasProcessTaskModel paasProcessTaskModel;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private DingtalkWorkrecordService dingtalkWorkrecordService;
    @Resource
    private WorkflowDingtalkService workflowDingtalkService;


    public void updateProcessData(ProcessNodeTaskUpdateDTO processNodeTaskUpdateDTO) throws XbbException {
        try {
            PaasProcessDataEntity paasProcessDataEntity = paasProcessDataModel.getByTaskId(processNodeTaskUpdateDTO.getProcessTaskId(), processNodeTaskUpdateDTO.getCorpid());
            if (paasProcessDataEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_DATA_NOT_EXIST);
            }
            ProcessDataUpdateDTO processDataUpdateDTO = new ProcessDataUpdateDTO();
            BeanUtil.copyProperties(processNodeTaskUpdateDTO, processDataUpdateDTO);
            processDataUpdateDTO.setFormDataId(paasProcessDataEntity.getFormDataId());
            if (Objects.nonNull(processNodeTaskUpdateDTO.getProcessTemplateNode())) {
                processDataUpdateDTO.setTemplateId(processNodeTaskUpdateDTO.getProcessTemplateNode().getTemplateId());
            }
            if (Objects.nonNull(processNodeTaskUpdateDTO.getOwnerId()) && !processNodeTaskUpdateDTO.getOwnerId().isEmpty()) {
                processDataUpdateDTO.setOwnerId(Objects.toString(processNodeTaskUpdateDTO.getOwnerId().get(0).getId(), ""));
            }
            processDataUpdateDTO.setData(processNodeTaskUpdateDTO.getDataList());
            //移除富文本数据
            //Object richTextData = richTextService.removeRichText(processNodeTaskUpdateDTO.getDataList());
            // 流程通过拷贝数据到form_data
            if (FlowStatusEnum.PASS.getType().equals(processNodeTaskUpdateDTO.getFlowStatus())) {
                if (Objects.equals(paasProcessDataEntity.getFormDataId(), 0L)) {
                    //新建进审批通过，流程数据保存到表单
                    ProcessDataAddFormDataDTO processDataAddFormDataDTO = new ProcessDataAddFormDataDTO();
                    BeanUtil.copyProperties(paasProcessDataEntity, processDataAddFormDataDTO);
                    BeanUtil.copyProperties(processNodeTaskUpdateDTO, processDataAddFormDataDTO);
                    processDataAddFormDataDTO.setOwnerId(processDataUpdateDTO.getOwnerId());
                    processDataAddFormDataDTO.setCreatorId(paasProcessDataEntity.getCreatorId());
                    processDataAddFormDataDTO.setDepartmentId(processNodeTaskUpdateDTO.getDepartmentId());
                    processDataAddFormDataDTO.setData(JSON.toJSONString(processNodeTaskUpdateDTO.getDataList()));
                    processDataAddFormDataDTO.setFlowStatus(FlowStatusEnum.PASS.getType());
                    processDataAddFormDataDTO.setSaasMark(processNodeTaskUpdateDTO.getSaasMark());
                    processDataAddFormDataDTO.setBusinessType(processNodeTaskUpdateDTO.getBusinessType());
                    processDataAddFormDataDTO.setSaasNeedRedundantAttrPoJo(processNodeTaskUpdateDTO.getSaasNeedRedundantAttrPoJo());
                    // TODO
                    ProcessDataAddFormDataVO processDataAddFormDataVO = processDataSynchronizedFormService.processDataAddFormData(processDataAddFormDataDTO);
                    if (Objects.isNull(processDataAddFormDataVO)) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
                    }
                    Long formDataId = processDataAddFormDataVO.getFormDataId();
                    processDataUpdateDTO.setFormDataId(formDataId);
                    //流程富文本数据保存至表单富文本
                    //richTextService.saveFormRichText(processDataAddFormDataDTO, formDataId, richTextData);
                } else {
                    //编辑进审批通过，更新表单数据
                    ProcessDataUpdateFormDataDTO processDataUpdateFormDataDTO = new ProcessDataUpdateFormDataDTO();
                    BeanUtil.copyProperties(paasProcessDataEntity, processDataUpdateFormDataDTO);
                    BeanUtil.copyProperties(processNodeTaskUpdateDTO, processDataUpdateFormDataDTO);
                    processDataUpdateFormDataDTO.setSaasMark(processNodeTaskUpdateDTO.getSaasMark());
                    processDataUpdateFormDataDTO.setBusinessType(processNodeTaskUpdateDTO.getBusinessType());
                    processDataUpdateFormDataDTO.setData(JSON.toJSONString(processNodeTaskUpdateDTO.getDataList()));
                    processDataUpdateFormDataDTO.setSaasNeedRedundantAttrPoJo(processNodeTaskUpdateDTO.getSaasNeedRedundantAttrPoJo());
                    processDataUpdateFormDataDTO.setFlowStatus(FlowStatusEnum.PASS.getType());
                    processDataUpdateFormDataDTO.setDepartmentId(processNodeTaskUpdateDTO.getDepartmentId());
                    // todo
                    processDataSynchronizedFormService.processDataUpdateFormData(processDataUpdateFormDataDTO);
                    //更新表单富文本
                    //richTextService.updateFormRichText(processDataUpdateFormDataDTO, richTextData);
                }
            } else if ((FlowStatusEnum.REJECT.getType().equals(processNodeTaskUpdateDTO.getFlowStatus()) || FlowStatusEnum.REVOKE.getType().equals(processNodeTaskUpdateDTO.getFlowStatus()))
                    && !Objects.equals(paasProcessDataEntity.getFormDataId(), 0L)) {
                /*if (Objects.equals(paasProcessDataEntity.getPostPosition(), 1)) {
                    // TODO 回退业务数据
                    FormDataDeleteBatchDTO formDataDeleteBatchDTO = new FormDataDeleteBatchDTO();
                    BeanUtil.copyProperties(processDataUpdateDTO, formDataDeleteBatchDTO);
                    formDataDeleteBatchDTO.setDataIdList(Collections.singletonList(paasProcessDataEntity.getFormDataId()));
                    formDataDeleteBatchDTO.setDistributorMark(DistributorMarkEnum.DISTRIBUTOR.getCode());
                    formDataDeleteBatchDTO.setFromProcess(1);
                    listBatchService.deleteBySingle(formDataDeleteBatchDTO);
                } else {*/
                    formDataHelp.updateFormDataStatus(paasProcessDataEntity, FlowStatusEnum.PASS.getType());
                //}
            }
            processDataUpdateDTO.setId(paasProcessDataEntity.getId());
            processDataUpdateDTO.setTaskId(processNodeTaskUpdateDTO.getProcessTaskId());
            try {
                // 下面这段会导致客户审批清空数字类型的数据，保存后又回来，目前接到多个相同bug，和杰哥沟通后先注释这段
                // // 没有key不更新字段
                // if (Objects.nonNull(processDataUpdateDTO.getData()) && StringUtil.isNotEmpty(paasProcessDataEntity.getData())) {
                //     processDataUpdateDTO.setData(JSON.parseObject(paasProcessDataEntity.getData()).fluentPutAll(processDataUpdateDTO.getData()));
                // }
                paasProcessDataService.update(processDataUpdateDTO);
                pushMessage(processNodeTaskUpdateDTO, paasProcessDataEntity);
            } catch (Exception e) {
                // 这里报错，表单数据，数据库会回滚，es不会回滚，所以目前暂时不处理报错
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasProcessTask更新流程数据出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }


    public void updateProcessType(ProcessNodeTaskUpdateDTO processNodeTaskUpdateDTO) throws XbbException {
        try {
            ProcessTaskUpdateDTO processTaskUpdateDTO = new ProcessTaskUpdateDTO();
            BeanUtil.copyProperties(processNodeTaskUpdateDTO, processTaskUpdateDTO);
            if (Objects.nonNull(processNodeTaskUpdateDTO.getProcessTemplateNode())) {
                processTaskUpdateDTO.setTemplateId(processNodeTaskUpdateDTO.getProcessTemplateNode().getTemplateId());
            }
            ProcessTaskUpdateVO processTaskUpdateVO = paasProcessTaskService.update(processTaskUpdateDTO);
            if (processTaskUpdateVO == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasProcessTask更新主流程状态出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    private void pushMessage(ProcessNodeTaskUpdateDTO processNodeTaskUpdateDTO, PaasProcessDataEntity paasProcessDataEntity) throws XbbException {
        Integer flowStatus = processNodeTaskUpdateDTO.getFlowStatus();
        if (!Objects.equals(flowStatus, FlowStatusEnum.PASS.getType()) && !Objects.equals(flowStatus, FlowStatusEnum.REJECT.getType())) {
            return;
        }
        String corpid = paasProcessDataEntity.getCorpid();
        Long taskId = paasProcessDataEntity.getTaskId();
        // 获取用户容器
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", 0);
        List<UserEntity> userList = userModel.findEntitys(param);
        if (userList == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.USER_NOT_EXIST);
        }
        Map<String, UserEntity> userMap = new HashMap<>(userList.size());
        userList.forEach((item) -> userMap.put(item.getUserId(), item));
        // 获取部门容器
        param.remove(ParameterConstant.COLUMNS);
        List<DepartmentEntity> departmentList = departmentModel.findEntitys(param);
        if (departmentList == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.DEPT_NOT_EXIST);
        }
        Map<String, DepartmentEntity> departmentMap = new HashMap<>(departmentList.size());
        departmentList.forEach((departmentItem) -> departmentMap.put(departmentItem.getId().toString(), departmentItem));

        param.remove(ParameterConstant.COLUMNS);
        param.put("nodeType", NodeTypeEnum.START_PROCESS_NODE.getNodeType());
        param.put("taskId", taskId);
        param.put("orderByStr"," id " + SortOrder.DESC);
        List<PaasProcessNodeTaskEntityExt> nodeTaskEntityExtList = paasProcessNodeTaskModel.findEntitys(param);
        Long dataId = paasProcessDataEntity.getId();
        Integer saasMark = paasProcessDataEntity.getSaasMark();
        Integer businessType = paasProcessDataEntity.getBusinessType();
        Long appId = paasProcessDataEntity.getAppId();
        Long menuId = paasProcessDataEntity.getMenuId();
        Long formId = paasProcessDataEntity.getFormId();

        String creatorId = paasProcessDataEntity.getCreatorId();
        String formName;
        if (Objects.equals(paasProcessDataEntity.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
            WorkOrderFormEntityExt workOrderFormEntityExt = workOrderFormModel.getByKey(formId, corpid);
            formName = workOrderFormEntityExt.getName();
        } else {
            PaasFormEntity paasFormEntity = paasFormModel.getByKey(formId, corpid);
            formName = paasFormEntity.getName();
        }
        String content = pushMessageHelp.getMessageContent(paasProcessDataEntity, userMap, departmentMap, processNodeTaskUpdateDTO );
        if (Objects.equals(flowStatus, FlowStatusEnum.PASS.getType())) {
            PushTypeEnum pushTypeEnum = PushTypeEnum.APPROVAL_AGREE_PUSH;
            PushRefTypePojo.Options options = new PushRefTypePojo.Options(appId, menuId, formId, Collections.singletonList(dataId), saasMark, businessType, taskId, nodeTaskEntityExtList.get(0).getId(), ProcessTypeEnum.CREATE.getValue());
            MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, Collections.singletonList(creatorId), Collections.singletonList(dataId), 0, DateTimeUtil.getInt(), I18nMessageUtil.getMessage(ProcessPushConstant.PROCESS_PASS_TITLE), String.format(I18nMessageUtil.getMessage(ProcessPushConstant.PROCESS_PASS_CONTENT), formName, content), null, options);
            baseProducer.sendMessage(pushTypeEnum, messageRabbitMqDTO);
        } else if (Objects.equals(flowStatus, FlowStatusEnum.REJECT.getType())) {
            PushTypeEnum pushTypeEnum = PushTypeEnum.APPROVAL_REFUSE_PUSH;
            PushRefTypePojo.Options options = new PushRefTypePojo.Options(appId, menuId, formId, Collections.singletonList(dataId), saasMark, businessType, taskId, nodeTaskEntityExtList.get(0).getId(), ProcessTypeEnum.CREATE.getValue());
            MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, Collections.singletonList(creatorId), Collections.singletonList(dataId), 0, DateTimeUtil.getInt(), I18nMessageUtil.getMessage(ProcessPushConstant.PROCESS_REFUSE_TITLE), String.format(I18nMessageUtil.getMessage(ProcessPushConstant.PROCESS_REFUSE_CONTENT), formName, content), null, options);
            baseProducer.sendMessage(pushTypeEnum, messageRabbitMqDTO);
        }
    }

    public void createTask(ProcessNodeTaskAddBatchDTO processNodeTaskAddBatchDTO) throws XbbException {
        try {
            List<PaasProcessNodeTaskEntity> nodeTaskList = new ArrayList<>();
            for (ProcessNodeTaskAddDTO nodeTask : processNodeTaskAddBatchDTO.getUserNodeTaskList()) {
                PaasProcessNodeTaskEntity paasProcessNodeTaskEntity = new PaasProcessNodeTaskEntity();
                // 给任务对象赋值
                BeanUtil.copyProperties(nodeTask, paasProcessNodeTaskEntity);
                long now = DateUtil.getInt();
                paasProcessNodeTaskEntity.setOpinion("");
                paasProcessNodeTaskEntity.setAttachment(JSONObject.toJSONString(new ArrayList<>()));
                paasProcessNodeTaskEntity.setImages(JSONObject.toJSONString(new ArrayList<>()));
                paasProcessNodeTaskEntity.setRevokeUserId("");
                paasProcessNodeTaskEntity.setActivationNode(0L);
                paasProcessNodeTaskEntity.setBackspaceNode(0L);
                paasProcessNodeTaskEntity.setTransferUserId("");
                paasProcessNodeTaskEntity.setAddTime(now);
                paasProcessNodeTaskEntity.setUpdateTime(now);
                paasProcessNodeTaskEntity.setLastNodeId(processNodeTaskAddBatchDTO.getLastNodeId());
                nodeTaskList.add(paasProcessNodeTaskEntity);
            }
            if (!nodeTaskList.isEmpty()) {
                paasProcessNodeTaskModel.insertBatch(nodeTaskList);
                //日志
                String userName = processNodeTaskAddBatchDTO.getLoginUserName();
                // 推送消息
                String content = pushMessage(nodeTaskList, processNodeTaskAddBatchDTO);
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_ADD_PROCESS_TASK), userName);
                mongoLogHelp.buildLog(processNodeTaskAddBatchDTO.getCorpid(), processNodeTaskAddBatchDTO.getUserId(), userName,
                        OperateModuleTypeEnum.PAAS_PROCESS_TASK, OperateTypeEnum.NEW, content, content, memo,
                        processNodeTaskAddBatchDTO.getHttpHeader());
                Long taskId = nodeTaskList.get(0).getTaskId();

                PaasProcessTaskEntity paasProcessTaskEntity = paasProcessTaskModel.getByKey(taskId.intValue(), processNodeTaskAddBatchDTO.getCorpid());
                String dingtalkProcessInstanceId = paasProcessTaskEntity.getDingtalkProcessInstanceId();
                if (StringUtil.isNotEmpty(dingtalkProcessInstanceId)) {

                    List<WorkrecordTaskOption> taskOptions = new ArrayList<>();
                    for (PaasProcessNodeTaskEntity paasProcessNodeTaskEntity : nodeTaskList) {

                        if (!Objects.equals(paasProcessNodeTaskEntity.getTaskType(), TaskTypeEnum.UNTREATED.getType())) {
                            continue;
                        }

                        WorkrecordTaskOption taskOption = new WorkrecordTaskOption();
                        // 审批人
                        taskOption.setUserId(paasProcessNodeTaskEntity.getUserId());
                        // 复用OA消息的 options = new PushRefTypePojo.Options(appId, menuId, formId, Collections.singletonList(dataId), saasMark, businessType, taskId, startNodeTask.getId(), ProcessTypeEnum.CREATE.getValue());
                        PushRefTypePojo.Options options = new PushRefTypePojo.Options(paasProcessNodeTaskEntity.getAppId(), paasProcessNodeTaskEntity.getMenuId(), paasProcessNodeTaskEntity.getFormId(), null,
                                paasProcessTaskEntity.getSaasMark(), paasProcessTaskEntity.getBusinessType(), taskId, paasProcessNodeTaskEntity.getId(), ProcessTypeEnum.TODO.getValue());
                        taskOption.setOptions(options);
                        taskOptions.add(taskOption);
                    }

                    if (CollectionsUtil.isNotEmpty(taskOptions)) {
                        WorkrecordTaskDTO workrecordTaskDTO = new WorkrecordTaskDTO();
                        workrecordTaskDTO.setCorpid(processNodeTaskAddBatchDTO.getCorpid());
                        workrecordTaskDTO.setDingtalkProcessInstanceId(dingtalkProcessInstanceId);
                        workrecordTaskDTO.setTaskOptions(taskOptions);
                        workflowDingtalkService.createDingtalkTask(workrecordTaskDTO);
                    }
                }
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasProcessTask数据库生成流程任务出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    private String pushMessage(List<PaasProcessNodeTaskEntity> nodeTaskList, ProcessNodeTaskAddBatchDTO processNodeTaskAddBatchDTO) throws XbbException {
        String corpid = nodeTaskList.get(0).getCorpid();
        // 获取用户容器
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", 0);
        List<UserEntity> userList = userModel.findEntitys(param);

        Map<String, UserEntity> userMap = new HashMap<>(userList.size());
        userList.forEach((item) -> userMap.put(item.getUserId(), item));
        // 获取部门容器
        param.remove(ParameterConstant.COLUMNS);
        List<DepartmentEntity> departmentList = departmentModel.findEntitys(param);

        Map<String, DepartmentEntity> departmentMap = new HashMap<>(departmentList.size());
        departmentList.forEach((departmentItem) -> departmentMap.put(departmentItem.getId().toString(), departmentItem));

        Long taskId = nodeTaskList.get(0).getTaskId();
        PaasProcessDataEntity paasProcessDataEntity = paasProcessDataModel.getByTaskId(taskId, corpid);
        Long appId = paasProcessDataEntity.getAppId();
        Long menuId = paasProcessDataEntity.getMenuId();
        Long formId = paasProcessDataEntity.getFormId();
        Long dataId = paasProcessDataEntity.getId();
        Integer saasMark = paasProcessDataEntity.getSaasMark();
        Integer businessType = paasProcessDataEntity.getBusinessType();
        String content = pushMessageHelp.getMessageContent(paasProcessDataEntity, userMap, departmentMap, processNodeTaskAddBatchDTO);
        String formName;
        if (Objects.equals(paasProcessDataEntity.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
            WorkOrderFormEntityExt workOrderFormEntityExt = workOrderFormModel.getByKey(formId, corpid);
            formName = workOrderFormEntityExt.getName();
        } else {
            PaasFormEntity paasFormEntity = paasFormModel.getByKey(paasProcessDataEntity.getFormId(), corpid);
            formName = paasFormEntity.getName();
        }
        PushTypeEnum pushTypeEnum;
        PushRefTypePojo.Options options;
        MessageRabbitMqDTO messageRabbitMqDTO;
        PaasProcessTaskEntity paasProcessTaskEntity = paasProcessTaskModel.getByKey(taskId.intValue(), corpid);
        UserEntity creatorUser = userModel.getByKeyIngoreDel(paasProcessTaskEntity.getCreatorId(), corpid);
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("nodeTypeIn", Arrays.asList(NodeTypeEnum.PROCESS_NODE.getNodeType(), NodeTypeEnum.START_PROCESS_NODE.getNodeType()));
        params.put("taskType", TaskTypeEnum.COMMIT.getType());
        params.put("corpid", corpid);
        params.put("taskId", taskId);
        params.put("del", 0);
        params.put("orderByStr"," id " + SortOrder.DESC);
        List<PaasProcessNodeTaskEntityExt> nodeTaskEntityExtList = paasProcessNodeTaskModel.findEntitys(params);
        // 发起人消息
        PaasProcessNodeTaskEntityExt startNodeTask = null;
        for (PaasProcessNodeTaskEntityExt paasProcessNodeTaskEntityExt : nodeTaskEntityExtList) {
            if (Objects.equals(paasProcessNodeTaskEntityExt.getNodeType(), NodeTypeEnum.START_PROCESS_NODE.getNodeType())) {
                startNodeTask = paasProcessNodeTaskEntityExt;
            }
        }
        // 当生成开始节点任务时，不发送给发起人消息，其他类型需要发送给发起者消息
        if (startNodeTask != null && !(startNodeTask.getTemplateNodeId().equals(nodeTaskList.get(0).getLastNodeId()))
                && !(NodeTypeEnum.START_PROCESS_NODE.getNodeType().equals(nodeTaskEntityExtList.get(0).getNodeType()))) {
            UserEntity lastUser = null;
            if (!nodeTaskEntityExtList.isEmpty()) {
                lastUser = userModel.getByKey(nodeTaskEntityExtList.get(0).getUserId(), corpid);
            } else {
                return content;
            }
            pushTypeEnum = PushTypeEnum.APPROVAL_NODE_CHANGE_PUSH;
            if (Objects.nonNull(lastUser)) {
                options = new PushRefTypePojo.Options(appId, menuId, formId, Collections.singletonList(dataId), saasMark, businessType, taskId, startNodeTask.getId(), ProcessTypeEnum.CREATE.getValue());
                messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, Collections.singletonList(paasProcessTaskEntity.getCreatorId()), Collections.singletonList(taskId), 0, DateTimeUtil.getInt(), I18nMessageUtil.getMessage(ProcessPushConstant.PROCESS_NODE_STATUS_CHANGE_TITLE), String.format(I18nMessageUtil.getMessage(ProcessPushConstant.PROCESS_NODE_STATUS_CHANGE_CONTENT), formName, content, lastUser.getName()), null, options);
                baseProducer.sendMessage(pushTypeEnum, messageRabbitMqDTO);
            }
        }
        for (PaasProcessNodeTaskEntity paasProcessNodeTaskEntity : nodeTaskList) {
            Integer taskType = paasProcessNodeTaskEntity.getTaskType();
            Long nodeId = paasProcessNodeTaskEntity.getId();
            String userId = paasProcessNodeTaskEntity.getUserId();
            if (Objects.equals(taskType, TaskTypeEnum.UNTREATED.getType())) {
                pushTypeEnum = PushTypeEnum.APPROVAL_NODE_CHANGE_PUSH;
                options = new PushRefTypePojo.Options(appId, menuId, formId, Collections.singletonList(dataId), saasMark, businessType, taskId, nodeId, ProcessTypeEnum.TODO.getValue());
                messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, Collections.singletonList(userId), Collections.singletonList(taskId), 0, DateTimeUtil.getInt(), I18nMessageUtil.getMessage(ProcessPushConstant.PROCESS_NODE_CHANGE_TITLE), String.format(I18nMessageUtil.getMessage(ProcessPushConstant.PROCESS_ADD_CONTENT), creatorUser.getName(), formName, content), null, options);
                baseProducer.sendMessage(pushTypeEnum, messageRabbitMqDTO);
            } else if (Objects.equals(paasProcessNodeTaskEntity.getTaskType(), TaskTypeEnum.CC.getType())) {
                pushTypeEnum = PushTypeEnum.APPROVAL_CARBON_COPY_PUSH;
                options = new PushRefTypePojo.Options(appId, menuId, formId, Collections.singletonList(dataId), saasMark, businessType, taskId, nodeId, ProcessTypeEnum.CC.getValue());
                messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, Collections.singletonList(userId), Collections.singletonList(taskId), 0, DateTimeUtil.getInt(), I18nMessageUtil.getMessage(ProcessPushConstant.PROCESS_CARBON_COPY_TITLE), String.format(I18nMessageUtil.getMessage(ProcessPushConstant.PROCESS_CARBON_COPY_CONTENT), creatorUser.getName(), formName, content), null, options);
                baseProducer.sendMessage(pushTypeEnum, messageRabbitMqDTO);
            }
        }
        return content;
    }
}
